package com.fs.sw.common.jpa.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * HIS JPA Base.
 *
 * @author shen.xy
 */
@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {

	/**
	 * Execute a NamedQuery and return the query results as an untyped List.
	 * Parameter is '?' in query JPQL.
	 *
	 * @param namedQuery
	 *            parameter is value of NamedQuery
	 * @param params
	 *            parameter is query parameter
	 *
	 * @return a list of the results
	 */
	List<T> exeQueryIdxParm(String namedQuery, Map<Integer, Object> params);

	/**
	 * Execute a NamedQuery and return the query results as an untyped List.
	 * Parameter is ':name' in query JPQL.
	 *
	 * @param namedQuery
	 *            parameter is value of NamedQuery
	 * @param params
	 *            parameter is query parameter
	 *
	 * @return a list of the results
	 */
	List<T> exeQueryNameParm(String namedQuery, Map<String, Object> params);

	/**
	 * Support paging. Execute a NamedQuery and return the query results as an
	 * untyped List. Parameter is '?' in query JPQL.
	 *
	 * @param namedQuery
	 *            parameter is value of NamedQuery
	 * @param params
	 *            parameter is query parameter
	 * @param pageNum
	 *            parameter
	 * @param pageSize
	 *            parameter
	 *
	 * @return a list of the results
	 */
	List<T> exeQueryIdxParm(String namedQuery, Map<Integer, Object> params, int pageNum, int pageSize);

	/**
	 * Support paging. Execute a NamedQuery and return the query results as an
	 * untyped List. Parameter is ':name' in query JPQL.
	 *
	 * @param namedQuery
	 *            parameter is value of NamedQuery
	 * @param params
	 *            parameter is query parameter
	 * @param pageNum
	 *            parameter
	 * @param pageSize
	 *            parameter
	 *
	 * @return a list of the results
	 */
	List<T> exeQueryNameParm(String namedQuery, Map<String, Object> params, int pageNum, int pageSize);

	/**
	 * Execute a custom JPQL and return the query results as an untyped List.
	 * Parameter is '?' in query JPQL.
	 *
	 * @param jpql
	 *            parameter is a JPQL
	 * @param params
	 *            parameter is query parameter
	 *
	 * @return a list of the results
	 */
	List<T> exeQueryCustIdxParm(String jpql, Map<Integer, Object> params);

	/**
	 * Execute a custom JPQL and return the query results as an untyped List.
	 * Parameter is ':name' in query JPQL.
	 *
	 * @param jpql
	 *            parameter is a JPQL
	 * @param params
	 *            parameter is query parameter
	 *
	 * @return a list of the results
	 */
	List<T> exeQueryCustNameParm(String jpql, Map<String, Object> params);

	/**
	 * Support paging. Execute a custom JPQL and return the query results as an
	 * untyped List. Parameter is ':name' in query JPQL.
	 *
	 * @param namedQuery
	 *            parameter is a JPQL
	 * @param params
	 *            parameter is query parameter
	 * @param pageNum
	 *            parameter
	 * @param pageSize
	 *            parameter
	 *
	 * @return a list of the results
	 */
	List<T> exeQueryCustIdxParm(String jpql, Map<Integer, Object> params, int pageNum, int pageSize);

	/**
	 * Support paging. Execute a custom JPQL and return the query results as an
	 * untyped List. Parameter is ':name' in query JPQL.
	 *
	 * @param jpql
	 *            parameter is a JPQL
	 * @param params
	 *            parameter is query parameter
	 * @param pageNum
	 *            parameter
	 * @param pageSize
	 *            parameter
	 *
	 * @return a list of the results
	 */
	List<T> exeQueryCustNameParm(String jpql, Map<String, Object> params, int pageNum, int pageSize);

	/**
	 * Execute a NamedQuery and return the query results as a string. Parameter is
	 * '?' in query JPQL.
	 * NqI = namedQuery and Map<Integer, Object>
	 *
	 * @param namedQuery
	 *            parameter is value of NamedQuery
	 * @param params
	 *            parameter is query parameter
	 *
	 * @return a string of the result
	 */
	Object getSingleResultNqI(String namedQuery, Map<Integer, Object> params);

	/**
	 * Execute a NamedQuery and return the query results as a string. Parameter is
	 * ':name' in query JPQL.
	 * NqS = namedQuery and Map<String, Object>
	 *
	 * @param namedQuery
	 *            parameter is value of NamedQuery
	 * @param params
	 *            parameter is query parameter
	 *
	 * @return a string of the result
	 */
	Object getSingleResultNqS(String namedQuery, Map<String, Object> params);

	/**
	 * Execute a custom JPQL and return the query results as a string. Parameter is
	 * '?' in query JPQL.
	 * JpqlI = JPQL and Map<Integer, Object>
	 *
	 * @param jpql
	 *            parameter is a JPQL
	 * @param params
	 *            parameter is query parameter
	 *
	 * @return a string of the result
	 */
	Object getSingleResultJpqlI(String jpql, Map<Integer, Object> params);

	/**
	 * Execute a custom JPQL and return the query results as a string. Parameter is
	 * ':name' in query JPQL.
	 * JpqlS = JPQL and Map<String, Object>
	 *
	 * @param jpql
	 *            parameter is a JPQL
	 * @param params
	 *            parameter is query parameter
	 *
	 * @return a string of the result
	 */
	Object getSingleResultJpqlS(String jpql, Map<String, Object> params);
	
	
	List<T> exeNativeQueryIdxParm(String jpql, Map<Integer, Object> params);
	
	List<T> exeNativeQueryParm(String jpql, Map<String, Object> params);
	
	List<T> exeNativeQueryParm(String jpql, Map<String, Object> params, int pageNum,
                               int pageSize);
	
	void execBatchInsert(List<T> list, int batchSize);

	T findOneWithGraph(Class<T> domainClass,ID id, String graphName);

}